objective-c维基百科笔记

objective-c维基百科学习笔记

objective-c

好吧,上面只是简单的实验一下插入图片的效果。
插入图片之前在控制器中输入了如下代码:

1
2
cd /xianghui/hexo/blog
sudo npm https://github.com/CodeFalling/hexo-asset-image --save

目的是为了实现在使用macdown写文章的时候可以插入图片。

消息传递

在objective-c中与其说是对象之间互相调用方法倒不如说是对象之间在进行着消息的传递
在objective-c中送一个消息给对象(或者说传递一个消息)

1
[obj method: argument]

那么以下举一个简单的例子:

1
[car fly]

在objective-c中可以这样理解:
“发一个fly消息给car对象“,fly是信息,car是信息的接受者。car在收到这个消息之后会选择如何实现这个消息,如果car类别中有fly方法,则运行方法内的代码,如果没有fly方法,则程序依旧可以正常编译,只不过运行的时候会抛出异常。

  • 运行期间才处理消息,允许发送消息给未知对象
  • 可以将消息发给对象集合而不需要一一检查每个对象的类型,具备消息转送的机制
  • 空对象nil接受消息之后默认为不做事

类的定义与实现

Objective-c中强制将类的定义(interface)和类的实现(implemention)分为两个部分。
类的定义通常一.h结尾,而类的实现通常一.m结尾(和c的一样)。

interface

清楚的定义了类的名称,类的方法,类的数据成员。以关键字@interface开始,@end结束

1
2
3
4
5
6
7
8
9
10
11
@interface MyObject : NSObject {
int memberVar1; // 实体变量
id memberVar2;
}
+(return_type) class_method; // 类方法
-(return_type) instance_method1; // 实例方法
-(return_type) instance_method2: (int) p1;
-(return_type) instance_method3: (int) p1 andPar: (int) p2;
@end

方法前面的 +/- 号代表函数的类型:加号(+)代表类方法(class method),不需要实例就可以调用,与C++ 的静态函数(static member function)相似。减号(-)即是一般的实例方法(instance method)。
Objective-C定义一个新的方法时,名称内的冒号(:)代表参数传递,不同于C语言以数学函数的括号来传递参数。Objective-C方法使得参数可以夹杂于名称中间,不必全部附缀于方法名称的尾端,可以提高程序可读性。设定颜色RGB值的方法为例:

1
2
3
- (void) setColorToRed: (float)red Green: (float)green Blue:(float)blue; /* 声明方法*/
[myColor setColorToRed: 1.0 Green: 0.8 Blue: 0.2]; /* 使用方法*/

这个方法的签名是setColorToRed:Green:Blue

implementation

实现区包含了方法的实现以及定义私有(private)变量及方法。 以关键字@implementation作为区块起头,@end结尾。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
@implementation MyObject {
int memberVar3; //私有实体变量
}
+(return_type) class_method {
.... //method implementation
}
-(return_type) instance_method1 {
....
}
-(return_type) instance_method2: (int) p1 {
....
}
-(return_type) instance_method3: (int) p1 andPar: (int) p2 {
....
}
@end

interface区和implementation区都可以定义变量,但是两者的访问权限不同,Interface区块内的实体变量默认权限为protected,声明于implementation区块的实体变量则默认为private,故在Implementation区块定义私有成员更合乎面向对象之封装原则,因为如此,类的·私有信息就不需曝露于公开interface(.h文件)中。

创建对象

objective-c创建对象使用两个消息:alloc以及init。alloc的作用是分配内存,init的作用是初始化对象。

1
MyObject * my = [[MyObject alloc] init];

但是在objective-c 2.0 中,如果创建对象不使用参数,那么可以直接使用new关键字。

1
MyObject * my = [MyObject new];

协议(protocol)

  • 协议是一组没有方法的列表,任何的类都可以采纳并且具体实现这组方法。
  • 协议类似java中的“接口”
  • 正式协议类似于java中的接口,它是一系列方法的列表,任何类都可以声明自身实现了某个协议。Objective-C 2.0版本允许标记协议中某些方法为可选的(Optional),这样编译器就不会强制实现这些可选的方法。

语法:
协议以关键字@protocol作为区块起始,@end结束,中间为方法列表

1
2
3
4
@protocol Locking
- (void)lock;
- (void)unlocking;
@end

动态类型

  • Objective-c 具备动态类型:即消息发送给任何对象实体,无论对象实体的公开接口中有没有对应的方法。
  • 一个对象收到消息之后,他有三种处理消息的可能手段,第一是回应该消息并运行方法,若无法回应,则可以转发消息给其他对象,若以上两者均无,就要处理无法回应而抛出的例外。只要进行三者之其一,该消息就算完成任务而被丢弃。若对“nil”(空对象指针)发送消息,该消息通常会被忽略,取决于编译器选项可能会抛出例外。

转发

Objective-C允许对一个对象发送消息,不管它是否能够响应之。除了响应或丢弃消息以外,对象也可以将消息转发到可以响应该消息的对象。转发可以用于简化特定的设计模式,例如观测器模式代理模式

类别(category)

  • 在objective-c的设计中,一个主要的考虑即为大型代码框架的维护。而在oc中采用“分类”的概念来实现分解代码的目的。
  • 一个分类可以将方法的实现分解为一系列分离的文件。程序员可以将一组相关的方法放入一个分类之中,使得程序具备可读性。

举例(创建了integer类,但是只定义了属性,然后新增分类display以拓展功能):
interger.h

1
2
3
4
5
6
7
8
9
10
11
#import <objc/Object.h>
@interface Integer : Object
{
@private
int integer;
}
@property (assign, nonatomic) integer;
@end

interger.m

1
2
3
4
5
6
7
#import "Integer.h"
@implementation Integer
@synthesize integer;
@end

display.h

1
2
3
4
5
6
#import "Integer.h"
@interface Integer(Display)
- (id) showstars;
- (id) showint;
@end

display.m

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
#import "Display.h"
@implementation Integer(Display)
- (id) showstars
{
int i, x = self.integer;
for(i=0; i < x; i++)
printf("*");
printf("\n");
return self;
}
- (id) showint
{
printf("%d\n", self.integer);
return self;
}
@end

属性

  • 属性总是为公共的,其目的为提供外部类访问(也可能为只读)类的内部变量的方法。
  • 属性可以被声明为“readonly”,即只读的,也可以提供储存方法包括“assign”,“copy”或“retain”(简单的赋值、复制或增加1引用计数)。
  • 默认的属性是原子的,即在访问时会加锁以避免多线程同时访问同一对象,也可以将属性声明为“nonatomic”(非原子的),避免产生锁。
1
2
3
4
5
6
7
8
9
10
11
12
@interface Person : NSObject {
@public
NSString *name;
@private
int age;
}
@property(copy) NSString *name;
@property(readonly) int age;
-(id)initWithAge:(int)age;
@end
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
@implementation Person
@synthesize name;
@dynamic age;
-(id)initWithAge:(int)initAge
{
age = initAge; // 注意:直接赋给成员变量,而非属性
return self;
}
-(int)age
{
return 29; // 注意:并非返回真正的年龄
}
@end

垃圾收集

当垃圾收集启用时,所有的对象都是收集器的工作对象。普通的C指针可以以“strong”修饰,标记指针指向的对象仍在使用中。被标记为“weak”的指针不被计入收集器的计数中,并在对象被回收时改写为“nil”。iOS上的Objective-C 2.0实现中不包含垃圾收集器。垃圾收集器运行在一个低优先级的后台线程中,并可以在用户动作时暂停,从而保持良好的用户体验。

坚持原创技术分享,您的支持将鼓励我继续创作!